//
//  RFCollectionViewHelper.swift
//  LSBase
//
//  Created by Roffa Zhou on 2021/8/9.
//

import Foundation
import UIKit
import SnapKit

//MARK: collectionView中数据model需遵循的协议
public protocol RFCollectionCellItemProtocol{
    ///加载cell
    var cellForRowCallback: ((IndexPath) -> Void)? { get set }
    ///将要显示cell
    var willDisplayCallback: ((IndexPath) -> Void)? { get set }
    ///点击cell回调
    var didSelectCellCallback: ((IndexPath) -> Void)? { get set }
    ///绑定cell
    func bindCell() -> UICollectionViewCell.Type
    ///绑定头视图或尾视图
    func bindSupplementaryView() -> UICollectionViewCell.Type
    ///创建cell
    func dequeueReusableCell(collectionView: UICollectionView, indexPath: IndexPath) -> UICollectionViewCell
   
}
public extension RFCollectionCellItemProtocol {
    var cellForRowCallback: ((IndexPath) -> Void)? {
        get {
            return nil
        }
        set {

        }
    }
    var willDisplayCallback: ((IndexPath) -> Void)? {
        get {
            return nil
        }
        set {

        }
    }
    var didSelectCellCallback: ((IndexPath) -> Void)? {
        get {
            return nil
        }
        set {

        }
    }
    func dequeueReusableCell(collectionView: UICollectionView, indexPath: IndexPath) -> UICollectionViewCell {
        let cellClass = bindCell()
        let identifier = String.init(describing: cellClass)
        let collectionCell: UICollectionViewCell = collectionView.dequeueReusableCell(withReuseIdentifier: identifier, for: indexPath)
       
        (collectionCell as? RFCollectionCellProtocol)?.ls_setItem(self)
        return collectionCell
    }
    func dequeueReusableView(collectionView: UICollectionView, kind: String = UICollectionView.elementKindSectionHeader, indexPath: IndexPath) -> UICollectionReusableView {
        let cellClass = bindSupplementaryView()
        let identifier = String.init(describing: cellClass)
        let supplementView = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: identifier+kind, for: indexPath)
       
        
        return supplementView
    }
}

//MARK:- cell遵循的协议
public protocol RFCollectionCellProtocol {
    func ls_setItem(_ item: RFCollectionCellItemProtocol)
}


/// <#Description#>
public class RFCollectionViewHelper: NSObject{
    public var dataSource = [Any]()
    public var bMutilSection = false        //是否有多个section，如有多个section，读取dataSource方式会发生变化
    private weak var delegate: UICollectionViewDelegate?
    public init(delegate: UICollectionViewDelegate? = nil) {
        self.delegate = delegate
    }
    public override func forwardingTarget(for aSelector: Selector!) -> Any? {
        if super.responds(to: aSelector) {
            return self
        }else if let delegate = delegate, delegate.responds(to: aSelector) {
            return delegate
        }
        return self
    }
    public override func responds(to aSelector: Selector!) -> Bool {
        if let delegate = delegate {
            return super.responds(to: aSelector) || delegate.responds(to: aSelector)
        }
        return super.responds(to: aSelector)
    }
    
    /**下面callback与cellItemProtocol功能类似，区别于：itemProtocol可用于一条一条处理，  此处用于批量处理*/
    ///加载cell。
    private var cellCallback: ((UICollectionViewCell, RFCollectionCellItemProtocol, IndexPath) -> Void)?
    private var supplementViewCallback: ((UICollectionReusableView, RFCollectionCellItemProtocol, IndexPath) -> Void)?  //头尾视图点击响应
    ///将要显示cell
    private var displayCallback: ((RFCollectionCellItemProtocol, IndexPath) -> Void)?
    ///点击cell回调
    private var selectCallback: ((RFCollectionCellItemProtocol, IndexPath) -> Void)?
    

    /// 使用UICollectionViewFlowLayout创建CollectionView
    /// - Parameters:
    ///   - superView: 需要加载的父视图. 会铺满父视图
    ///   - itemSize: cell的大小
    ///   - direction: 滚动方向
    /// - Returns: 建立好的collectionview
    public func createCollectionView(_ superView: UIView, itemSize: CGSize, direction: UICollectionView.ScrollDirection = .vertical) -> UICollectionView{
        let vl = UICollectionViewFlowLayout()
        vl.minimumInteritemSpacing = 18
        vl.scrollDirection = direction
        vl.itemSize = itemSize
        
        let collectionView = UICollectionView(frame: .zero, collectionViewLayout: vl)
        collectionView.backgroundColor = .white
        collectionView.showsHorizontalScrollIndicator = false
        collectionView.showsVerticalScrollIndicator = false
        collectionView.dataSource = self
        collectionView.delegate = self
        superView.addSubview(collectionView)
        collectionView.snp.makeConstraints { make in
            make.edges.equalTo(UIEdgeInsets.zero)
        }
        
        return collectionView
    }
    
    @discardableResult
    public func cellForRow(_ closure:@escaping (UICollectionViewCell,RFCollectionCellItemProtocol,IndexPath) -> Void) -> Self {
        cellCallback = closure
        return self
    }
    @discardableResult
    public func willDisplay(_ closure:@escaping (RFCollectionCellItemProtocol,IndexPath) -> Void) -> Self {
        displayCallback = closure
        return self
    }
    @discardableResult
    public func selectRow(_ closure:@escaping (RFCollectionCellItemProtocol, IndexPath) -> Void) -> Self {
        selectCallback = closure
        return self
    }
}
// MARK: - ---UICollectionViewDelegate
extension RFCollectionViewHelper: UICollectionViewDelegate {
//    public func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
//        if let delegate = delegate, delegate.responds(to: #selector(tableView(_:didSelectRowAt:))) {
//            delegate.tableView!(tableView, didSelectRowAt: indexPath)
//        }else {
//            dataSource[indexPath.row].didSelectCellCallback?(indexPath)
//            selectCallback?(dataSource[indexPath.row], indexPath)
//        }
//    }
//    public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
//        if let delegate = delegate, delegate.responds(to: #selector(tableView(_:heightForRowAt:))) {
//            return delegate.tableView!(tableView, heightForRowAt: indexPath)
//        }else {
//            if (rowHeight != nil), dataSource[indexPath.row].cellHeight() != UITableView.automaticDimension{  //当全局设置了cell高度，并且每个item没有设置高，使用全局高
//                return rowHeight!
//            }
//            return dataSource[indexPath.row].cellHeight()
//        }
//    }
//    public func tableView(_ tableView: UITableView, willDisplay cell: UITableViewCell, forRowAt indexPath: IndexPath) {
//        if let delegate = delegate, delegate.responds(to: #selector(tableView(_:willDisplay:forRowAt:))) {
//            delegate.tableView!(tableView, willDisplay: cell, forRowAt: indexPath)
//        }else {
//            dataSource[indexPath.row].willDisplayCallback?(indexPath)
//            displayCallback?(dataSource[indexPath.row], indexPath)
//        }
//    }
}
//MARK: - ---UICollectionViewDataSource
extension RFCollectionViewHelper: UICollectionViewDataSource {
    public func numberOfSections(in collectionView: UICollectionView) -> Int {
        if bMutilSection {
            return dataSource.count
        }
        return 1
    }
    public func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if dataSource.count < 1 {
            fatalError("LSCollectionViewHelper.dataSource必须定义")
        }
        if bMutilSection {
            return (dataSource[section] as! Array<RFCollectionCellItemProtocol>).count
        }
        return dataSource.count
    }
    public func collectionView(_ collectionView: UICollectionView, viewForSupplementaryElementOfKind kind: String, at indexPath: IndexPath) -> UICollectionReusableView {
        let view = getItem(indexPath).dequeueReusableView(collectionView: collectionView, kind: kind, indexPath: indexPath)
        return view
//        return UICollectionReusableView()
    }
    public func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let item:RFCollectionCellItemProtocol = getItem(indexPath)
            
        let cell = item.dequeueReusableCell(collectionView: collectionView, indexPath: indexPath)
        item.cellForRowCallback?(indexPath)
        cellCallback?(cell, item, indexPath)
        return cell
    }
    
    private func getItem(_ indexPath: IndexPath) -> RFCollectionCellItemProtocol{
        var item:RFCollectionCellItemProtocol
        if bMutilSection {  //多个section
            if let array = dataSource[indexPath.section] as? Array<RFCollectionCellItemProtocol> {
                item = array[indexPath.row]
            }else{
                fatalError("当bMutilSection=true,传入的LSCollectionViewHelper.dataSource必须为数组")
            }
        }else{
            if let it = dataSource[indexPath.row] as? RFCollectionCellItemProtocol {
                item = it
            }else{
                fatalError("LSCollectionViewHelper.dataSource必须遵循RFCollectionCellItemProtocol")
            }
        }
        return item
    }
    
}
